<?php 
/**
 *  模版引擎扩展
 *
 * @copyright	http://www.discuz.com
 * @author 		光哥 modify  <439884988@qq.com>
 * @version		1.0 - 2012-03-26
 * @package		Extends
 *
 */

if(!defined("CHARSET")) define("CHARSET","utf-8");//字符编码

class Discuz{
	//note var
	public $rewrite=false;//是否开启 伪静态 rewrite
	public $rewrite_rule=array(); //设置伪静态规则
	public $defaulttpldir;//默认的模板
	public $tpldir;//模板目录
	public $objdir;//编译缓存目录
	public $tplfile;//模板文件
	public $objfile;//编译文件
	public $tplid=1;//模板编号
	public $currdir='default';//当前风格目录
	public $vars=array();//note 变量表
	public $removeblanks=false;//移除空格
	public $stdout='display';//输出类型
	function __construct() {
	}
	//note publlic
	function assign($k, $v) {
		$this->vars[$k] = $v;
	}
	//note publlic
	function display($file) {
		extract($this->vars, EXTR_SKIP);
		include $this->getObj($file);
	}
	function getObj($file, $tpldir = '') {
		$subdir = ($pos = strpos($file, '/')) === false ? '' : substr($file, 0, $pos);
		$file = $subdir ? substr($file, $pos + 1) : $file;
		$this->tplfile = ($tpldir ? $tpldir : $this->tpldir).'/'.($subdir ? $subdir.'/' : '').$file;
		$this->objfile = $this->objdir.'/'.($tpldir ? '' : $this->tplid.'_').($subdir ? $subdir.'_' : '').$file.'.php';
		//note 默认目录
		if(@filemtime($this->tplfile) === FALSE) {
			$this->tplfile = $this->defaulttpldir.'/'.($subdir ? $subdir.'/' : '').$file;
		}
		//note 判断是否比较过期
		if(!file_exists($this->objfile) || DEBUG && @filemtime($this->objfile) < filemtime($this->tplfile)) {
			$this->compile();
		}
		return $this->objfile;
	}
	function getTpl($file) {
		$subdir = ($pos = strpos($file, '/')) === false ? '' : substr($file, 0, $pos);
		$file = $subdir ? substr($file, $pos + 1) : $file;
		$tplfile = $this->tpldir.'/'.($subdir ? $subdir.'/' : '').$file;
		if(@filemtime($tplfile) === FALSE) {
			$tplfile = $this->defaulttpldir.'/'.($subdir ? $subdir.'/' : '').$file;
		}
		return $tplfile;
	}
	function compile() {
		$var_regexp = "\@?\\\$[a-zA-Z_]\w*(?:\[[\w\.\"\'\[\]\$]+\])*";
		$vtag_regexp = "\<\?=(\@?\\\$[a-zA-Z_]\w*(?:\[[\w\.\"\'\[\]\$]+\])*)\?\>";
		$const_regexp = "\{([\w]+)\}";
		$template = file_get_contents($this->tplfile);
		for($i = 1; $i <= 3; $i++) {
			if(strpos($template, '{subtpl') !== FALSE) {
				if(DEBUG == 2) {
					$template = str_replace('{subtpl ', '{tpl ', $template);
				} else {
					$template = preg_replace("/[\n\r\t]*\{subtpl\s+([a-z0-9_:\/]+)\}[\n\r\t]*/ies", "file_get_contents(\$this->getTpl('\\1'))", $template);
				}
			}
		}
		$remove = array(
				'/(^|\r|\n)\/\*.+?(\r|\n)\*\/(\r|\n)/is',
				'/\/\/note.+?(\r|\n)/i',
				'/\/\/debug.+?(\r|\n)/i',
				'/(^|\r|\n)(\s|\t)+/',
				'/(\r|\n)/',
		);
		$this->removeblanks && $template = preg_replace($remove, '', $template);
		$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
		$template = preg_replace("/\{($var_regexp)\}/", "<?=\\1?>", $template);
		$template = preg_replace("/\{($const_regexp)\}/", "<?=\\1?>", $template);
		$template = preg_replace("/(?<!\<\?\=|\\\\)$var_regexp/", "<?=\\0?>", $template);
		$template = preg_replace("/\<\?=(\@?\\\$[a-zA-Z_]\w*)((\[[\\$\[\]\w]+\])+)\?\>/ies", "\$this->arrayindex('\\1', '\\2')", $template);
		$template = preg_replace("/\{\{eval (.*?)\}\}/ies", "\$this->stripvtag('<? \\1?>')", $template);
		$template = preg_replace("/\{eval (.*?)\}/ies", "\$this->stripvtag('<? \\1?>')", $template);
		$template = preg_replace("/[\n\r\t]*\{echo\s+(.+?)\}[\n\r\t]*/ies", "\$this->stripvtag('<? echo \\1; ?>','')", $template);
		$template = preg_replace("/\{for (.*?)\}/ies", "\$this->stripvtag('<? for(\\1) {?>')", $template);
		$template = preg_replace("/\{elseif\s+(.+?)\}/ies", "\$this->stripvtag('<? } elseif(\\1) { ?>')", $template);
		for($i=0; $i<2; $i++) {
			$template = preg_replace("/\{loop\s+$vtag_regexp\s+$vtag_regexp\s+$vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '\\2', '\\3', '\\4')", $template);
			$template = preg_replace("/\{loop\s+$vtag_regexp\s+$vtag_regexp\}(.+?)\{\/loop\}/ies", "\$this->loopsection('\\1', '', '\\2', '\\3')", $template);
		}
		$template = preg_replace("/\{if\s+(.+?)\}/ies", "\$this->stripvtag('<? if(\\1) { ?>')", $template);
		$template = preg_replace("/\{tpl\s+(\w+?)\}/is", "<? include \$this->getObj(\"\\1\");?>", $template);
		$template = preg_replace("/\{tpl\s+(.+?)\}/ise", "\$this->stripvtag('<? include \$this->getObj(\"\\1\"); ?>')", $template);
		$template = preg_replace("/\{tmptpl\s+(\w+?)\}/is", "<? include \$this->getObj(\"\\1\", \$this->objdir);?>", $template);
		$template = preg_replace("/\{tmptpl\s+(.+?)\}/ise", "\$this->stripvtag('<? include \$this->getObj(\"\\1\", \$this->objdir); ?>')", $template);
		$template = preg_replace("/\{else\}/is", "<? } else { ?>", $template);
		$template = preg_replace("/\{\/if\}/is", "<? } ?>", $template);
		$template = preg_replace("/\{\/for\}/is", "<? } ?>", $template);
		$template = preg_replace("/$const_regexp/", "<?=\\1?>", $template);//note {else} 也符合常量格式，此处要注意先后顺序
		$template = preg_replace("/(\\\$[a-zA-Z_]\w+\[)([a-zA-Z_]\w+)\]/i", "\\1'\\2']", $template);
	
		$this->mkdir_recursive($this->objdir, 0755);
		$fp = fopen($this->objfile, 'w');
		fwrite($fp, $template);
		fclose($fp);
	}
	function arrayindex($name, $items) {
		$items = preg_replace("/\[([a-zA-Z_]\w*)\]/is", "['\\1']", $items);
		return "<?=$name$items?>";
	}
	function stripvtag($s) {
	$vtag_regexp = "\<\?=(\@?\\\$[a-zA-Z_]\w*(?:\[[\w\.\"\'\[\]\$]+\])*)\?\>";
		return preg_replace("/$vtag_regexp/is", "\\1", str_replace("\\\"", '"', $s));
	}
					function loopsection($arr, $k, $v, $statement) {
					$arr = $this->stripvtag($arr);
					$k = $this->stripvtag($k);
					$v = $this->stripvtag($v);
					$statement = str_replace("\\\"", '"', $statement);
					return $k ? "<? foreach((array)$arr as $k => $v) {?>$statement<?}?>" : "<? foreach((array)$arr as $v) {?>$statement<? } ?>";
					}
					function fetch($file){
						ob_start();
						$this->display($file);
						$content = ob_get_contents();
						ob_end_clean();
						return $content;
	
	}
						function mkdir_recursive($pathname, $mode)
						{
						is_dir(dirname($pathname)) || $this->mkdir_recursive(dirname($pathname), $mode);
						return is_dir($pathname) || @mkdir($pathname, $mode);
	}
	
		function __destruct() {
		}
}
/*
 $tpl = new template();
$tpl->rewrite=true;//开启rewrite 需要服务器支持
$tpl->rewrite_rule=array(array("/index\.php/"),array("index.html")); //rewrite规则
$tpl->assign("indexurl","index.php");
$tpl->assign("str","我是字符串啦啦啦");
$tpl->assign("ec","我是被echo出来的");
$tpl->assign("subhtml","{subtpl ttt}这是用来引入一个模板文件的，这个就是引入ttt.htm");
$tpl->assign("a",array('dasdasd'.'bbbbbbb','cccccccccccccc'));
$tpl->assign("i",1);
echo $tpl->fetch("index");
*/
?>